package ocg.common.re.read;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jayway.jsonpath.JsonPath;
import ocg.common.re.file.FileOperation;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.testng.annotations.Test;

import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JsonAssign {

    static Logger logger = LogManager.getLogger ( PropertiesAssign.class );

    public static Map<String,List<String>> jsonMap = new HashMap<> ();

    String json = null;

    public JsonAssign() {
    }

    public JsonAssign(String json) {
        this.json = json;
    }

    public JsonAssign( File path ) {
        this.json = FileOperation.stringRead( path );
    }

    public JSONObject jsonObject(){
        if (json != null) {
            JSONObject object =JSON.parseObject ( json );
            return object;
        }
        return null;
    }

    public <T>T jsonPath( String path ){
        if (json != null) {
            return JsonPath.parse( json ).read( path );
        }
        return null;
    }

    /**
     * 用来递归扫描Json数据
     * @param jsonStr
     * @param beanName
     */
    public static void defaultGenerate(String jsonStr , String beanName){

        //用来保存一个object中的entry信息
        List<String> fieldList = new ArrayList<> ();

        //先把传进来的String转成jsonObject
        JSONObject rootObject = JSON.parseObject(jsonStr);

        //对rootObject中的每个值进行遍历
        for (Map.Entry<String, Object> entry : rootObject.entrySet()) {

            if(entry.getValue().toString().startsWith("[")){
                //Value值如果是List的话
                fieldList.add(entry.getKey());
                JSONArray jsonArray = rootObject.getJSONArray(entry.getKey());
                if(jsonArray.size()>0){
                    String arrayString = jsonArray.get(0).toString();
                    defaultGenerate(arrayString,entry.getKey());
                }
            }else if(entry.getValue().toString().startsWith("{")) {
                //Value值是Object，需要进行循环调用
                fieldList.add(entry.getKey());
                defaultGenerate(rootObject.getJSONObject(entry.getKey()).toJSONString(), entry.getKey());

            }else {
                //Value值就是普通的值
                fieldList.add(entry.getKey());
            }

        }
        jsonMap.put(beanName,fieldList);
    }

    /**
     * 通过反射，将json数据注入到类对象中
     * @param className             与json文件对应的类对象类名
     */
    public static void getJosnAssign( Class<?> className ){

//        getSimpleName() 获取类名（ConfingTest）
//        StringBuffer : 字符串拼接 获取文件名
//        获取文件相对路径
        String fileName = new StringBuffer().append("json").append( File.separator ).append( className.getSimpleName() ).append( ".json" ).toString();

        logger.info ( "读取文件：" + fileName );

        /**
         * /D:/SL/AutoTests/target/test-classes/json\HttpReq.json
         */
        String path = JsonAssign.class.getClassLoader().getResource ( "" ).getPath ()+ fileName;

        logger.info ( path );

        File file = new File ( path );

        if ( file.exists () ) {

            String json = FileOperation.stringRead( file );

            JSONObject object = JSON.parseObject ( json );

            try {
                //            获取类对象
                Class clzss = Class.forName ( className.getName () );

                //            getFields()：获得某个类的所有的公共（public）的字段，包括父类中的字段。
                //            getDeclaredFields()：获得某个类的所有声明的字段，即包括public、private和proteced，但是不包括父类的申明字段。

                Field field[] = clzss.getDeclaredFields ();

                Object o = clzss.newInstance ();

                for (Field f : field ) {

                    Object value = object.get ( f.getName () );

                    //用java反射机制改变私有静态的Final Field

                    f.setAccessible(true);
                    try {
                        f.set ( o, value );
                    } catch (IllegalAccessException e) {
                        e.printStackTrace ();
                    }
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace ();
            } catch (IllegalAccessException e) {
                e.printStackTrace ();
            } catch (InstantiationException e) {
                e.printStackTrace ();
            }


        }

    }

}
